package com.liyunc.demo.comp.common.utils;

import lombok.extern.log4j.Log4j2;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;

/**
 * @author liyuncong
 * @version 1.0
 * @file HttpResponseUtils
 * @brief HttpResponseUtils
 * @details HttpResponseUtils
 * @date 2022-06-21
 *
 * Edit History
 * ----------------------------------------------------------------------------
 * DATE                        NAME               DESCRIPTION
 * 2022-06-21                      liyuncong          Created
 */
@Log4j2
public class HttpResponseUtils {

    private static final String HEADER_CONTENT_TYPE = "Content-Type";
    private static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition";
    private static final String HEADER_ATTACHMENT = "attachment; filename=";

    public static ResponseEntity<InputStreamResource> sendAttachment(
        String attachmentFilename,
        String mimeType,
        File file
    ) {
        final MediaType mediaType = MediaType.parseMediaType(mimeType);
        return sendAttachment(attachmentFilename, mediaType, file);
    }

    public static ResponseEntity<InputStreamResource> sendAttachment(
        String attachmentFilename,
        String mimeType,
        InputStream inputStream
    ) {
        final MediaType mediaType = MediaType.parseMediaType(mimeType);
        return sendAttachment(attachmentFilename, mediaType, inputStream);
    }

    public static ResponseEntity<InputStreamResource> sendAttachment(
        String attachmentFilename,
        MediaType mediaType,
        File file
    ) {
        try (InputStream inputStream = Files.newInputStream(file.toPath())) {
            return sendAttachment(attachmentFilename, mediaType, inputStream);
        } catch (IOException exception) {
            log.error("Failed to convert file to stream {}", attachmentFilename, exception);
            return ResponseEntity
                .status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(null);
        }
    }

    public static ResponseEntity<InputStreamResource> sendAttachment(
        String attachmentFilename,
        MediaType mediaType,
        InputStream inputStream
    ) {
        try {
            InputStreamResource resource = new InputStreamResource(inputStream);
            String filename = encoding(attachmentFilename);
            return ResponseEntity
                .ok()
                .contentType(mediaType)
                .header(HEADER_CONTENT_DISPOSITION, HEADER_ATTACHMENT + filename)
                .contentLength(inputStream.available())
                .body(resource);
        } catch (IOException exception) {
            log.error("Failed to send file stream {}", attachmentFilename, exception);
            return ResponseEntity
                .status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(null);
        }
    }

    /**
     * 处理字符串为utf-8编码格式。
     *
     * @param value 待处理字符串
     * @return 处理结果
     */
    private static String encoding(String value) {
        return new String(
            value.getBytes(StandardCharsets.UTF_8),
            StandardCharsets.ISO_8859_1
        );
    }
}